package com.superafroman.asm;

import java.util.ArrayList;
import java.util.List;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.commons.EmptyVisitor;

/**
 * Simple {@link ClassVisitor} to collect class annotation information. Used for
 * locating classes based on their annotations.
 */
public class ClassAnnotationCollector extends EmptyVisitor {

    private List<String> annotations;

    private boolean readAnnotations;

    public ClassAnnotationCollector() {
        annotations = new ArrayList<String>();
        readAnnotations = true;
    }

    public List<String> getAnnotations() {
        return annotations;
    }

    /**
     * Record the annotation description.
     */
    @Override
    public AnnotationVisitor visitAnnotation(String description, boolean visible) {
        if (readAnnotations) {
            annotations.add(description);
        }
        return super.visitAnnotation(description, visible);
    }

    /**
     * Finish reading the class. This resets the readAnnotations flag to true.
     */
    @Override
    public void visitEnd() {
        readAnnotations = true;
        super.visitEnd();
    }

    /**
     * Set the readAnnotations flag to false. We only want to read in class
     * annotations.
     */
    @Override
    public FieldVisitor visitField(int access, String name, String desc,
            String signature, Object value) {
        readAnnotations = false;
        return super.visitField(access, name, desc, signature, value);
    }

    /**
     * Set the readAnnotations flag to false. We only want to read in class
     * annotations.
     */
    @Override
    public MethodVisitor visitMethod(int access, String name, String desc,
            String signature, String[] exceptions) {
        readAnnotations = false;
        return super.visitMethod(access, name, desc, signature, exceptions);
    }
}
